<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      html,
      body {
        margin: 0;
        width: 100%;
        height: 100%;
      }
      #canvas {
        width: 100%;
        height: 100%;
        display: block;
      }
    </style>
  </head>
  <body>
    <canvas id="canvas"></canvas>

    <script>
      const canvas = document.querySelector("#canvas");
      const ctx = canvas.getContext("2d");

      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;

      ctx.fillStyle = "#000";
      ctx.fillRect(0, 0, window.innerWidth, window.innerHeight);

      const fontSize = 15; // 字体大小，同时用来当成一个文字的宽高
      const textColor = "#00ff00";

      const colNum = Math.floor(window.innerWidth / fontSize); // 列数

      const colsYList = new Array(colNum); // 每一列下一个字符个数
      colsYList.fill(1);

      // 获取随机字符串
      function getRandomStr() {
        const str = "01";
        const index = Math.floor(Math.random() * str.length);
        return str[index];
      }

      // 绘制画布
      function draw() {
        ctx.fillStyle = "rgba(0,0,0,.15)";
        ctx.fillRect(0, 0, window.innerWidth, window.innerHeight); // 生成一层半透明膜，得到文字透明度逐渐变深效果

        ctx.fillStyle = textColor;
        ctx.font = `${fontSize}px Georgia`;

        for (let i = 0; i < colsYList.length; i++) {
          const x = fontSize * i;
          const y = fontSize * colsYList[i];
          ctx.fillText(getRandomStr(), x, y);

          // 当超出画布且1%几率成功，那就回到最上面，实现参差不齐的下落效果
          if (y > window.innerHeight && Math.random() > 0.99) {
            colsYList[i] = 0; // 回到最上面
          } else {
            // 往下
            colsYList[i]++;
          }
        }
      }

      draw();

      setInterval(draw, 50);
    </script>
  </body>
</html>
